#include "sys_resource.h"
#include "util-files.h"
/** 初始化一些资源资源 */
extern int thread_recv_pcie_signal;
/**
 * Start the file writing thread 
 * @param pwf this is parameters needed to write files
 */
void thread_save_file(PackWriteFile *pwf) {
    char thread_name[20];
    sprintf(thread_name, "%s%d", SAVE_TO_FILE_NAME, pwf->threadId);
    prctl(PR_SET_NAME, thread_name);

    OrderQueueBox *quBox = pwf->oqBox;
    BQueue *queue = NULL; 
    int threadId = pwf->threadId;
    FilePro * cfile; 
    int findex = 0;
    uint64 writebytes_count = 0;  //记录写入的总字节数
    while (1)
    {
        while (NULL != (queue = outputOrderQueueEle(quBox))) {
            ///开始写文件......
#ifdef  QUEUE_STATUS
            LOG_INFO("写入队列: %p, queue: %p, channel: %d \n", quBox, queue, queue->channel);
#endif               
            //获取对应的下标
            findex = GET_WRITE_FILE_INDEX(queue->channel, threadId);
            cfile = pwf->filePro + findex;
            save_tofile_with_queue(cfile, pwf, queue, queue->rbuf, queue->qlen);
            freeBQueue(queue);
        }
        
        if(!thread_recv_pcie_signal) {           
            LOG_INFO("threadId: %d, thread_id %d, 执行完毕, 保存文件 \n", threadId, pwf->thread_id);
            return;
        }
    }
}

/***
 * @param len write file thread num, 
 * @param recv_cmd directive parameter
 * @param qBox disorderly queue
 */
PackWriteFile * apply_resource(int len, RecvCmd *recv_cmd, BQueueBox *qBox) {
    struct tm* thread_start_tm;
    time_t thread_start_tv;
    time(&thread_start_tv);
    thread_start_tm = localtime(&thread_start_tv);
    PackWriteFile *pwf = (PackWriteFile *)malloc(sizeof(PackWriteFile) * len);
    LOG_EXAM_TEST("---> 申请: %p, [pwf] \n", pwf);
    PackWriteFile *cpwf = pwf;
    size_t threadId = 0;

    //判断磁盘是否挂载
    int isdir = access(SAVE_PATH, F_OK);
    // char *mount_path = "mount -t ceph 192.168.70.11,192.168.70.12:/ /mnt/cephfs/";
    // system(mount_path); //磁盘挂载
    // if(isdir) {
    //     LOG_ERROR("目录不存在:\n %s \n", mount_path);
    //     return;
    // }
    for (; threadId < len; threadId++) {
        pwf->size = len;
        pwf->threadId = threadId;
        pwf->recv_cmd = recv_cmd;
        pwf->qBox = qBox;
        pwf->oqBox = createOrderQueue(PCIE_QUEUE_NUM);
        pwf->directory = (uint8 *) malloc(sizeof(uint8) * FILE_NAME_SIZE);
        LOG_EXAM_TEST("---> 申请: %p, [pwf->directory] \n", pwf->directory);
        // sprintf(pwf->directory, "%s",  SAVE_PATH);
        sprintf(pwf->directory, "%s%02d/%02d/%02d/%04d/%02d%02d%02d/", 
            SAVE_PATH, recv_cmd->year, recv_cmd->month, 
             recv_cmd->date,                   //目录
             pwf->recv_cmd->Tasknum,
             recv_cmd->hour, 
             recv_cmd->min, 
             recv_cmd->sec                      //目录
        );
        if(KT_ERROR == CreateDir(pwf->directory)) {
            LOG_ERROR("#ERR: error to create directory, directory: %s \n", pwf->directory);
        }
        
        //每个文件限制的大小, 0 为不限制文件的大小
        if(recv_cmd->FileSize == 3) {
            pwf->fileLimitSize = 4;
        }else {
            pwf->fileLimitSize = recv_cmd->FileSize;
        }
        
        //每个线程保存可执行的最大文件数
        int thread_file_size = PCIE_FILE_SIZE; 
        pwf->fileProSize = thread_file_size;    
        pwf->filePro = (FilePro *)malloc(sizeof(FilePro) * thread_file_size);
        LOG_EXAM_TEST("---> 申请: %p, [pwf->filePro] \n", pwf->filePro);
        memset(pwf->filePro, 0x00, sizeof(FilePro) * thread_file_size);
        pthread_create(&pwf->thread_id, NULL, thread_save_file, (void *)pwf);
        LOG_DEBUG("threadID: %d, thread_id: %p, pwf: %p, oqBox: %p, cfile: %p, recvcmd: %p \n", 
            threadId, pwf->thread_id, pwf, pwf->oqBox, pwf->filePro, recv_cmd);
        *pwf++;
    }
    return cpwf;
}

/** 销毁资源 */
int free_resource(PackWriteFile *pwf, BQueueBox *qBox) {
    free(pwf->recv_cmd);
    PackWriteFile *cpwf = pwf;
    int plen = pwf->size;
    size_t i = 0;
    FilePro *filePro = NULL;
    while (i < plen) {
        LOG_DEBUG("线程id状态 thread_id: %d, threadId %d\n", pwf->thread_id, pwf->threadId);
        destoryOrderQueue(pwf->oqBox);  //销毁每个线程中的队列
        int num = 0;
        filePro = pwf->filePro;         //关闭队列中的文件
        while ((num++) < pwf->fileProSize) {
            if(filePro->flag == ISEXIST_YES) {
                file_close(filePro);
            }
            *filePro++;
        }
        LOG_EXAM_TEST("---> 释放: %p, [pwf->filePro] \n", pwf->filePro);
        free(pwf->filePro);             //销毁每个线程中的文件
        LOG_EXAM_TEST("---> 释放: %p, [pwf->directory] \n", pwf->directory);
        free(pwf->directory);           
        *pwf++;
        i++;
    }
    //销毁 pwf
    LOG_EXAM_TEST("---> 释放: %p, [pwf->directory] \n", cpwf);
    free(cpwf);
    cpwf = NULL;
    LOG_DEBUG("销毁每个线程中的有序队列, 并清除 文件读写! \n");

    //销毁有序队列
    if(destroyBQueue(qBox) != KT_OK) {
        LOG_ERROR("#ERR: 队列内存销毁失败 \n");
    }
    LOG_DEBUG("销毁无序队列内存块 \n");

    thread_recv_pcie_signal = 0;  //线程结束
}
